/*!
 * Timeline Widget 1.0 - 2015-06-12
 * http://www.neulion.com//
 */
$.widget("neulion.timeline", {
	// default options
	options: {
		dataFeedUrl: null,
		showComment: true,
		commentPosition: "top",
		showTwBtnIcon: true,
		showTwBtnText: true,
		twBtnPosition: "left",
		refreshInterval: 60, // unit: s
		lang: 'en' //eg. en, es;
	},
	timelineHeader: null,
	timelineContainer: null,
	timelineIntervalId: null,

	g_nlTexts: {
		'es': {
			"no_tweets": "No hay Tweets",
			"tweet_to": "Tweetear a"
		},
		'en': {
			"no_tweets": "No Tweets",
			"tweet_to": "Tweet to"
		}
	},

	_create: function ()
	{
		// add Class
		this.element.addClass("twitter-timeline");

		this._initLayout();
		this._loadData();

		// refresh new data
		var that = this;
		this.timelineIntervalId = setInterval(function () {
			that._loadData();
		}, that.options.refreshInterval * 1000);
	},
	// init layout
	_initLayout: function () {
		// Show comment or not
		var container = "<div class=\"twitter-timeline-container\"></div>";
		if (this.options.showComment) {
			var header = "<div class=\"twitter-timeline-header\"></div>";
			if (this.options.commentPosition == "bottom") { // Comment position: bottom
				this.element.html(container + header);

				this.timelineHeader = this.element.children(":last-child");
				this.timelineContainer = this.element.children(":first-child");
				// header-bottom
				this.timelineHeader.addClass("header-bottom");
				this.timelineContainer.addClass("header-bottom");
			} else {  // Comment position: top ; Default
				this.element.html(header + container);

				this.timelineHeader = this.element.children(":first-child");
				this.timelineContainer = this.element.children(":last-child");
				// header-top
				this.timelineContainer.addClass("header-top");
			}
		} else {										  //No comment,
			//this.element.append(container);
			this.element.html(container);
			this.timelineContainer = this.element.children(":first-child");
		}
		// hide icon
		if (!this.options.showTwBtnIcon) {
			this.timelineContainer.addClass("tw-btn-icon-hide");
		}
		// hide text
		if (!this.options.showTwBtnText) {
			this.timelineContainer.addClass("tw-btn-text-hide");
		}
		// position: left or right.(Default:left)
		if (this.options.twBtnPosition == "right") {
			this.timelineContainer.addClass("tw-btn-position-right");
		} else {
			this.timelineContainer.addClass("tw-btn-position-left");
		}
		this.timelineContainer.html("<div class='no-tweets'>Loading...</div>");
	},

	_loadData: function () {
		this._getDataScript(this.options.dataFeedUrl, this, this._dataCallback, true, 60);
	},

	_dataCallback: function () {
		var data = window.twitterData;
		var content = '';
		if (data.statusCode == 200) {
			var tweets = data.statuses;
			// data.searchCondition
			if (this.options.showComment) {
				var tweetQueries = "?text=";
				var hashTags = data.searchCondition.join(" ");
				tweetQueries += encodeURIComponent(hashTags);
				var headerContent = '<a class="timeline-header" target="_blank" href="https://twitter.com/intent/tweet' + tweetQueries + '">' + this._getText('tweet_to') + " " + hashTags + '</a>';
				this.timelineHeader.addClass("has-content");
				this.timelineHeader.html(headerContent);
			}
			if (tweets && tweets.length > 0)
			{
				content += '<ul>';
				for (var i = 0; i < tweets.length; i++)
				{
					try {
						var html = '';
						html += '<li class="tweet">';
						html += '	<a class="time" href="https://twitter.com/' + tweets[i].user.screen_name + '/status/' + tweets[i].id_str + '" target="_blank">' + this._calcTwitterTime(tweets[i].created_at) + '</a>';
						html += '	<div class="author">';
						html += '		<a href="https://twitter.com/intent/user?screen_name=' + tweets[i].user.screen_name + '" target="_blank">';
						html += '			<img src="' + tweets[i].user.profile_image_url_https + '"/>';
						html += '			<span class="full-name">' + tweets[i].user.name + '</span>';
						html += '			<span class="nick-name">@' + tweets[i].user.screen_name + '</span>';
						html += '		</a>';
						html += '	</div>';
						html += '	<div class="tw-content">' + this._unescapeHTML(linkify_entities(tweets[i])) + '</div>';
						html += '	<div class="tw-btns">';
						var replyHtml = '<a href="https://twitter.com/intent/tweet?in_reply_to=' + tweets[i].id_str + '"';
						var retweetHtml = '<a href="https://twitter.com/intent/retweet?tweet_id=' + tweets[i].id_str + '"';
						var favoriteHtml = '<a href="https://twitter.com/intent/favorite?tweet_id=' + tweets[i].id_str + '"';
						if (this.options.showTwBtnIcon) {
							replyHtml += ' class="reply"';
							retweetHtml += ' class="retweet"';
							favoriteHtml += ' class="favorite"';
						}
						replyHtml += ' >Reply</a>';
						retweetHtml += ' >Retweet</a>';
						favoriteHtml += ' >Favorite</a>';

						if (this.options.twBtnPosition == "right") {
							html += favoriteHtml;
							html += retweetHtml;
							html += replyHtml;
						} else {
							html += replyHtml;
							html += retweetHtml;
							html += favoriteHtml;
						}

						html += '</div></li>';
						content += html;
					} catch (ex) {
					}
				}
				content += '</ul>';
			}
			else {
				content += '<div class="no-tweets">' + this._getText("no_tweets") + '</div>';
			}
		}
		else {
			content += '<div class="no-tweets">' + this._getText("no_tweets") + '</div>';
		}
		this.timelineContainer.html(content);
	},

	_getText: function (key) {
		return this.g_nlTexts[this.options.lang][key] || this.g_nlTexts['en'][key];
	},
	// Get Data
	_getDataScript: function (url, that, callback, requireCache, cacheRound) {
		if (!$.isFunction(callback)) {
			requireCache = callback;
			cacheRound = requireCache;
		}
		requireCache = !!requireCache;
		if (requireCache && cacheRound > 0) {
			url = url + (url.indexOf('?') > -1 ? '&' : '?') + 't=' + parseInt(new Date().getTime() / (cacheRound * 1000));
		}
		$.ajax({
			url: url,
			dataType: "script",
			cache: requireCache,
			success: function () {
				callback.call(that);
			}
		});
	},

	//
	_calcTwitterTime: function (time) {
		var nowTime = new Date().getTime();
		var tweetTime = this._parseTwitterTime(time);
		var diffTime = nowTime - tweetTime;
		if (diffTime < 60 * 1000) {
			return Math.floor(diffTime / 1000) + 's';
		}
		else if (diffTime < 3600 * 1000) {
			return Math.floor(diffTime / (60 * 1000)) + 'm';
		}
		else if (diffTime < 24 * 3600 * 1000) {
			return Math.floor(diffTime / (3600 * 1000)) + 'h';
		}
		else {
			var timeDate = new Date(tweetTime);
			var shortMonth = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
			return timeDate.getDate() + ' ' + shortMonth[timeDate.getMonth()];
		}
	},

	//
	_unescapeHTML: function (html) {
		return $('<div/>').html(html).text();
	},

	//
	_parseTwitterTime: function (timeStr) {
		// Pattern: Tue Mar 27 13:55:20 +0000 2014
		var twitterTime = new Date(Date.parse(timeStr)).getTime();
		if (!twitterTime) {
			// Pattern: Tue Mar 27 13:55:20 UTC +0000 2014
			twitterTime = Date.parse(timeStr.replace(/( \+)/, ' UTC$1'));
		}
		return twitterTime;
	},

	// events bound via _on are removed automatically
	// revert other modifications here
	_destroy: function ()
	{
		// Clear
		window.clearInterval(this.timelineIntervalId);
		// remove generated elements
		this.element
				.removeClass("twitter-timeline")
				.text("")
				.empty();
	},

	// _setOptions is called with a hash of all options that are changing
	// always refresh when changing options
	_setOptions: function ()
	{
		// _super and _superApply handle keeping the right this-context
		this._superApply(arguments);
		//this._refresh();
	},

	// _setOption is called for each individual option that is changing
	_setOption: function (key, value)
	{
		// prevent invalid color values
		this._super(key, value);
	}
});

function twitterCallback(data)
{
	window.twitterData = data;
}


/*
 * twitter-entities.js
 * This function converts a tweet with "entity" metadata
 * from plain text to linkified HTML.
 *
 * See the documentation here: http://dev.twitter.com/pages/tweet_entities
 * Basically, add ?include_entities=true to your timeline call
 *
 * Copyright 2010, Wade Simmons
 * Licensed under the MIT license
 * http://wades.im/mons
 *
 * Requires jQuery
 */

function escapeHTML(text) {
	return $('<div/>').text(text).html()
}

function linkify_entities(tweet) {
	if (!(tweet.entities)) {
		return escapeHTML(tweet.text)
	}

	// This is very naive, should find a better way to parse this
	var index_map = {};
	var i;

	$.each(tweet.entities.urls, function (i, entry) {
		index_map[entry.indices[0]] = [entry.indices[1], function (text) {
			return "<a href='" + escapeHTML(entry.url) + "'>" + escapeHTML(text) + "</a>"
		}]
	});

	$.each(tweet.entities.hashtags, function (i, entry) {
		index_map[entry.indices[0]] = [entry.indices[1], function (text) {
			return "<a href='http://twitter.com/search?q=" + escape("#" + entry.text) + "'>" + escapeHTML(text) + "</a>"
		}]
	});

	$.each(tweet.entities.user_mentions, function (i, entry) {
		index_map[entry.indices[0]] = [entry.indices[1], function (text) {
			return "<a title='" + escapeHTML(entry.name) + "' href='http://twitter.com/" + escapeHTML(entry.screen_name) + "'>" + escapeHTML(text) + "</a>"
		}]
	});

	var result = "";
	var last_i = 0;

	// iterate through the string looking for matches in the index_map
	for (i = 0; i < tweet.text.length; ++i) {
		var ind = index_map[i];
		if (ind) {
			var end = ind[0];
			var func = ind[1];
			if (i > last_i) {
				result += escapeHTML(tweet.text.substring(last_i, i))
			}
			result += func(tweet.text.substring(i, end));
			i = end - 1;
			last_i = end
		}
	}

	if (i > last_i) {
		result += escapeHTML(tweet.text.substring(last_i, i))
	}

	return result
}